import { useEffect, useState } from 'react';
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
import { BsIntersect } from 'react-icons/bs';
import { red } from '@ant-design/colors';
import { CloseOutlined, PlusOutlined } from '@ant-design/icons';
import { useHandler } from '@cfe/hooks';
import styled from '@emotion/styled';
import { Button, Radio, Tag, Tooltip } from 'antd';
import produce from 'immer';
import uniqueId from 'lodash/uniqueId';

import { RadiusSpan } from '@/components/base';
import { tsFmtLongDate } from '@/utils/time';

import filterDataToRemoteFilter from '../utils/filterDataToRemoteFilter';
import getEduShowContent from '../utils/getEduShowContent';
import getShowContent from '../utils/getShowContent';

import { SELECTOR_TYPES } from './TagSelectorFilter';
const grid = 8;

const createTagString = (item) => {
  const { groupName, tags, customName, type, biz_name } = item;
  if (type === 'custom') {
    return customName;
  }
  if (type === 'extend_crowd') {
    return groupName;
  }
  if (type === 'crowd') {
    return groupName;
  }

  if (type === 'biz_tag') {
    if (biz_name) {
      return getEduShowContent(item);
    }
    return getShowContent(item);
  }

  const string = groupName + '：';
  const values = [];
  // 加一层保护
  if (tags) {
    for (const tag of tags) {
      const {
        tagType,
        tagValues,
        number,
        dateFrom,
        dateTo,
        numberFrom,
        numberTo,
      } = tag;
      if (
        SELECTOR_TYPES.ENUM === tagType ||
        SELECTOR_TYPES.TEXT === tagType ||
        SELECTOR_TYPES.Tree ||
        SELECTOR_TYPES.WithCoverage
      ) {
        const valueStrings = tagValues?.map((tagValue) => {
          return tagValue.valueText;
        });
        values.push(valueStrings);
      }
      if (tagType === SELECTOR_TYPES.NUMBER) {
        values.push(number);
      }
      if (tagType === SELECTOR_TYPES.DATERANGE) {
        values.push(`${tsFmtLongDate(dateFrom)}~${tsFmtLongDate(dateTo)}`);
      }

      if (tagType === SELECTOR_TYPES.RANGE) {
        values.push(`${numberFrom}~${numberTo}`);
      }
    }
  }

  return string + values.join(',');
};

const getItemStyle = (isDragging, draggableStyle) => ({
  // some basic styles to make the items look a bit nicer
  userSelect: 'none',
  padding: grid / 2,
  margin: `0 0 ${grid / 2}px 0`,

  // change background colour if dragging
  background: isDragging ? 'lightblue' : '#c6defd',
  whiteSpace: 'nowrap',
  textOverflow: 'ellipsis',
  overflow: 'hidden',
  width: '100%',
  display: 'flex',
  alignItems: 'center',

  // styles we need to apply on draggables
  ...draggableStyle,
});

// 加上 id，方便 map
const createUniId = (value) => {
  const valueWithIniId = produce(value, (draftValue) => {
    draftValue.filters.forEach((section) => {
      section.uniId = uniqueId();
      section.filters.forEach((list) => {
        list.uniId = uniqueId();
        list.filters.forEach((item) => {
          item.uniId = uniqueId();
        });
      });
    });
  });
  return valueWithIniId;
};

const DraggableList = ({ onChange, initialValue }) => {
  const [data, setData] = useState(createUniId(initialValue));
  const onDragEnd = useHandler((result) => {
    const { source, destination } = result;

    // dropped outside the list
    if (!destination) {
      return;
    }

    if (source.droppableId === destination.droppableId) {
      // 统一 list 移动不管
    }
    const [sourceSectionIndex, sourceListIndex] = source.droppableId
      .split('-')
      .map(Number);

    const [destinationSectionIndex, destinationListIndex] =
      destination.droppableId.split('-').map(Number);

    setData((data) =>
      produce(data, (draftData) => {
        // 删掉 destination 的那个 index
        const [moved] = draftData.filters[sourceSectionIndex].filters[
          sourceListIndex
        ].filters.splice(source.index, 1);
        draftData.filters[destinationSectionIndex].filters[
          destinationListIndex
        ].filters.splice(destination.index, 0, moved);
      }),
    );
  });

  // add
  const handleAddSection = useHandler(() => {
    setData((data) =>
      produce(data, (draftData) => {
        draftData.filters.push({
          type: 'or',
          filters: [{ type: 'and', filters: [], uniId: uniqueId() }],
          uniId: uniqueId(),
        });
      }),
    );
  });

  const handleAddList = useHandler((sectionIndex) => {
    setData((prevData) =>
      produce(prevData, (draftData) => {
        draftData.filters[sectionIndex].filters.push({
          type: 'and',
          filters: [],
          uniId: uniqueId(),
        });
      }),
    );
  });

  // // delete
  const handleDeleteList = useHandler((sectionIndex, listIndex) => {
    setData((data) =>
      produce(data, (draftData) => {
        draftData.filters[sectionIndex].filters.splice(listIndex, 1);
        // 如果 list 删没了，就直接删掉 section
        if (draftData.filters[sectionIndex].filters.length === 0) {
          draftData.filters.splice(sectionIndex, 1);
        }
      }),
    );
  });

  const handleDeleteTag = useHandler((sectionIndex, listIndex, itemIndex) => {
    setData((data) =>
      produce(data, (draftData) => {
        draftData.filters[sectionIndex].filters[listIndex].filters.splice(
          itemIndex,
          1,
        );
      }),
    );
  });

  // section logic
  const handleSectionLogic = useHandler((sectionIndex, value) => {
    setData((data) =>
      produce(data, (draftData) => {
        draftData.filters[sectionIndex].type = value;
      }),
    );
  });

  useEffect(() => {
    const result = filterDataToRemoteFilter(data);
    onChange(result);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [data]);

  return (
    <DragDropContext onDragEnd={onDragEnd}>
      {data.filters.map((section, sectionIndex) => {
        const { type, filters, uniId } = section;
        return (
          <div
            key={uniId}
            style={{
              display: 'flex',
              width: '100%',
              flexDirection: 'column',
            }}
          >
            <div
              style={{
                display: 'flex',
                alignItems: 'center',
                flexWrap: 'wrap',
              }}
            >
              {filters.map((dropableItem, listIndex) => {
                const { filters, uniId } = dropableItem;
                return (
                  <div
                    key={uniId}
                    style={{ display: 'flex', alignItems: 'center' }}
                  >
                    <Droppable droppableId={`${sectionIndex}-${listIndex}`}>
                      {(provided) => (
                        <DraggableContainer>
                          <Tooltip title="取交集">
                            <BsIntersect
                              style={{
                                position: 'absolute',
                                top: '50%',
                                transform: 'translate(-100%, -50%)',
                                color: '#096dd9',
                              }}
                            />
                          </Tooltip>
                          <div
                            ref={provided.innerRef}
                            style={{ height: '100%', flex: 1 }}
                          >
                            {filters.map((item, index) => {
                              const stringContent = createTagString(item);
                              const { uniId } = item;
                              // const dragId = getDragId(item)
                              return (
                                <Draggable
                                  key={uniId}
                                  draggableId={uniId}
                                  index={index}
                                >
                                  {(provided, snapshot) => (
                                    <Tag
                                      ref={provided.innerRef}
                                      {...provided.draggableProps}
                                      {...provided.dragHandleProps}
                                      style={getItemStyle(
                                        snapshot.isDragging,
                                        provided.draggableProps.style,
                                      )}
                                      closable
                                      onClose={() =>
                                        handleDeleteTag(
                                          sectionIndex,
                                          listIndex,
                                          index,
                                        )
                                      }
                                    >
                                      <div
                                        style={{
                                          width: '90%',
                                        }}
                                      >
                                        <Tooltip
                                          title={stringContent}
                                          mouseEnterDelay={1}
                                          placement="left"
                                        >
                                          <div
                                            style={{
                                              overflow: 'hidden',
                                              whiteSpace: 'nowrap',
                                              textOverflow: 'ellipsis',
                                            }}
                                          >
                                            {stringContent}
                                          </div>
                                        </Tooltip>
                                      </div>
                                    </Tag>
                                  )}
                                </Draggable>
                              );
                            })}
                            {provided.placeholder}
                          </div>
                          {filters.length === 0 && (
                            <Tooltip>
                              <div
                                style={{
                                  width: '20px',
                                  height: '20px',
                                  borderRadius: '50%',
                                  border: 'solid white 2px',
                                  backgroundColor: red[3],
                                  position: 'absolute',
                                  top: '-8px',
                                  right: '-8px',
                                  display: 'flex',
                                  justifyContent: 'center',
                                  alignItems: 'center',
                                }}
                              >
                                <Button
                                  type="text"
                                  icon={<CloseOutlined />}
                                  style={{ color: '#FFF' }}
                                  onClick={() =>
                                    handleDeleteList(sectionIndex, listIndex)
                                  }
                                />
                              </div>
                            </Tooltip>
                          )}
                        </DraggableContainer>
                      )}
                    </Droppable>
                    <Tooltip title="取并集">
                      <RadiusSpan>并</RadiusSpan>
                    </Tooltip>
                  </div>
                );
              })}

              <Button
                icon={<PlusOutlined />}
                style={{ margin: '0 5px' }}
                onClick={() => handleAddList(sectionIndex)}
              >
                添加
              </Button>
            </div>
            {sectionIndex !== data.filters.length - 1 && (
              <div
                style={{
                  display: 'flex',
                  justifyContent: 'center',
                  background: 'white',
                  padding: 5,
                }}
              >
                <Radio.Group
                  size="small"
                  optionType="button"
                  options={[
                    { label: '交', value: 'and' },
                    { label: '并', value: 'or' },
                    { label: '差', value: 'not' },
                  ]}
                  value={type}
                  onChange={(e) => {
                    handleSectionLogic(sectionIndex, e.target.value);
                  }}
                />
              </div>
            )}
          </div>
        );
      })}

      <Button
        icon={<PlusOutlined />}
        style={{ margin: '0 5px', width: '100%', borderStyle: 'dashed' }}
        onClick={handleAddSection}
      >
        添加
      </Button>
    </DragDropContext>
  );
};

export default DraggableList;

const DraggableContainer = styled.div`
  background: #096dd90d;
  padding: 8px;
  width: 240px;
  height: 300px;
  margin: 8px 20px;
  position: relative;
  ::after {
    position: absolute;
    top: 0;
    left: 0;
    display: block;
    width: 20px;
    height: 100%;
    min-height: 220px;
    border-top: solid #096dd9 1px;
    border-bottom: solid #096dd9 1px;
    border-left: solid #096dd9 1px;
    content: '';
  }
`;
